﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Build.Workflow.Activities;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Build.Workflow;
using Microsoft.TeamFoundation.Lab.Workflow.Activities;

namespace HybridLab.Workflow.Activities.UI
{
	internal class BuildDetailsEx : PropertyErrorManager
	{
		private BuildDefinitionEx buildDefinition;
		private BuildDetailEx buildDetail;
		private List<BuildDetailEx> buildList;
		private PlatformConfiguration configuration;
		private PlatformConfigurationList configurationList;
		private string customBuildPath;
		private bool isTeamSystemBuild;
		private bool queueNewBuild;

		// Methods
		private void LoadBuilds()
		{
			buildList = new List<BuildDetailEx>();
			BuildDetail = new BuildDetailEx(null);
			buildList.Add(this.BuildDetail);
			if (BuildDefinition != null)
			{
				IBuildDetail[] detailArray = BuildDefinition.Definition.BuildServer.QueryBuilds(BuildDefinition.Definition);
				if (detailArray != null)
				{
					foreach (IBuildDetail detail in detailArray)
					{
						if ((detail.Status == BuildStatus.Succeeded) || (detail.Status == BuildStatus.PartiallySucceeded))
						{
							buildList.Add(new BuildDetailEx(detail));
						}
					}
				}
			}
		}

		private void LoadConfigurations()
		{
			configurationList = null;
			PlatformConfiguration tempConfig = Configuration;
			Configuration = null;
			if (this.BuildDefinition != null)
			{
				if (QueueNewBuild || BuildDetail == null || BuildDetail.IsLatestOption)
				{
					object settingsObj = WorkflowHelpers.DeserializeProcessParameters(BuildDefinition.Definition.ProcessParameters).Values.FirstOrDefault(o => typeof(BuildSettings) == o.GetType());
                    if (settingsObj != null)
					{
                        BuildSettings settings = settingsObj as BuildSettings;
						if (settings.HasPlatformConfigurations)
						{
							configurationList = settings.PlatformConfigurations;
						}
					}
				}
				else
				{
					configurationList = new PlatformConfigurationList();
					foreach (IBuildInformationNode node in this.BuildDetail.Build.Information.GetNodesByType("ConfigurationSummary", true))
					{
						PlatformConfiguration item = new PlatformConfiguration();
						item.Configuration = node.Fields["Flavor"];
						item.Platform = node.Fields["Platform"];
						configurationList.Add(item);
					}
				}
				if (configurationList != null)
				{
					Configuration = configurationList.FirstOrDefault(c => PlatformConfigurationEquals(c, tempConfig));
					if (Configuration == null && configurationList.Count == 1)
					{
						Configuration = configurationList[0];
					}
				}
			}
		}

		internal static bool PlatformConfigurationEquals(PlatformConfiguration platformConfiguration1, PlatformConfiguration platformConfiguration2)
		{
			if (platformConfiguration1 == null && platformConfiguration2 == null)
			{
				return true;
			}
			if (platformConfiguration1 == null || platformConfiguration2 == null)
			{
				return false;
			}
			return (string.Equals(platformConfiguration1.Platform, platformConfiguration2.Platform, StringComparison.OrdinalIgnoreCase) && string.Equals(platformConfiguration1.Configuration, platformConfiguration2.Configuration, StringComparison.OrdinalIgnoreCase));
		}

		private void ValidateBuildDefinition()
		{
			if (IsTeamSystemBuild && BuildDefinition == null)
			{
				base.SetPropertyError("BuildDefinition", "Select a build definition");
			}
			else
			{
				base.ClearPropertyError("BuildDefinition");
			}
		}

		private void ValidateConfiguration()
		{
			if (IsTeamSystemBuild && BuildDefinition != null && configurationList != null && configurationList.Count > 1 && configuration == null)
			{
				base.SetPropertyError("Configuration", "Select a configuration to be used for deployment and testing");
			}
			else
			{
				base.ClearPropertyError("Configuration");
			}
		}

		private void ValidateCustomBuildPath()
		{
			if (!IsTeamSystemBuild && string.IsNullOrEmpty(this.CustomBuildPath))
			{
				base.SetPropertyError("CustomBuildPath", "Specify the build path");
			}
			else
			{
				base.ClearPropertyError("CustomBuildPath");
			}
		}

		// Properties
		internal BuildDefinitionEx BuildDefinition
		{
			get
			{
				return buildDefinition;
			}
			set
			{
				buildDefinition = value;
				ValidateBuildDefinition();
				LoadBuilds();
				LoadConfigurations();
			}
		}

		internal BuildDetailEx BuildDetail
		{
			get
			{
				return buildDetail;
			}
			set
			{
				buildDetail = value;
				LoadConfigurations();
			}
		}

		internal List<BuildDetailEx> BuildList
		{
			get
			{
				return this.buildList;
			}
		}

		internal PlatformConfiguration Configuration
		{
			get
			{
				return configuration;
			}
			set
			{
				configuration = value;
				ValidateConfiguration();
			}
		}

		internal List<PlatformConfiguration> ConfigurationList
		{
			get
			{
				return configurationList;
			}
		}

		internal string CustomBuildPath
		{
			get
			{
				return customBuildPath;
			}
			set
			{
				customBuildPath = value;
				ValidateCustomBuildPath();
			}
		}

		internal bool IsTeamSystemBuild
		{
			get
			{
				return isTeamSystemBuild;
			}
			set
			{
				isTeamSystemBuild = value;
				ValidateBuildDefinition();
				ValidateCustomBuildPath();
				ValidateConfiguration();
			}
		}

		internal bool QueueNewBuild
		{
			get
			{
				return queueNewBuild;
			}
			set
			{
				queueNewBuild = value;
				LoadConfigurations();
			}
		}
	}
}
